home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb / sprite / RCS / ptraceMips.c,v < prev    next >
Encoding:
Text File  |  1991-07-03  |  10.2 KB  |  398 lines

  1. head     1.1;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.1
  10. date     91.07.02.22.58.41;  author jhh;  state Exp;
  11. branches ;
  12. next     ;
  13.  
  14.  
  15. desc
  16. @@
  17.  
  18.  
  19.  
  20. 1.1
  21. log
  22. @Initial revision
  23. @
  24. text
  25. @/*
  26.  * ptrace.c --
  27.  *
  28.  *    Routines for creating a Unix like debugger interface to Sprite.
  29.  *
  30.  * Copyright 1991 Regents of the University of California
  31.  * Permission to use, copy, modify, and distribute this
  32.  * software and its documentation for any purpose and without
  33.  * fee is hereby granted, provided that this copyright
  34.  * notice appears in all copies.  The University of California
  35.  * makes no representations about the suitability of this
  36.  * software for any purpose.  It is provided "as is" without
  37.  * express or implied warranty.
  38.  *
  39.  * $Header: /sprite/src/kernel/mach/spur.md/RCS/machConfig.c,v 1.2 88/11/11 15:3
  40. 6:43 mendel Exp $ SPRITE (Berkeley)
  41.  */
  42.  
  43. #include <stdio.h> 
  44. #include "sprite.h"
  45. #include "status.h"
  46. #include <sys/types.h>
  47. #include "sys/ptrace.h"
  48. #include <errno.h>
  49. #include <proc.h>
  50. #include <signal.h>
  51. #include <sys/wait.h>
  52.  
  53. static int mapStatusToErrno();
  54.  
  55. /* 
  56.  *----------------------------------------------------------------------
  57.  *
  58.  * ptrace --
  59.  *
  60.  *    Emulate Unix ptrace system call.
  61.  *
  62.  * Results:
  63.  *    An integer.
  64.  *
  65.  * Side effects:
  66.  *
  67.  *----------------------------------------------------------------------
  68.  */
  69.  
  70. int
  71. ptrace (request,pid,addr,data, addr2)
  72.      int request;    /* Data
  73.      int pid;            /* Process id of debugee. */
  74.      char *addr;        
  75.      int data;
  76.      char *addr2;
  77. {
  78.      extern int    errno;
  79.      Proc_DebugState process_state;
  80.      int    returnData;
  81.      ReturnStatus    status;
  82.  
  83.  
  84. #if 0
  85.      printf("ptrace: request %d, id 0x%x, addr 0x%x, data 0x%x\n", 
  86.      request, pid, addr);
  87. #endif
  88.      errno = 0;
  89.      if ((int) addr < 0) {
  90.      printf("Negative addr\n");
  91.      }
  92.      switch (request) {
  93.         case PT_TRACE_ME: {      /* 0, by tracee to begin tracing */
  94.          extern int    _execDebug;
  95.          /*
  96.           * This is a hack to emulate the ptrace(0) request.  ptrace(0) 
  97.           * seems to cause the exec() to stop after the first instruction.
  98.           * Setting _execDebug to true causes the Proc_Exec call to
  99.           * enter the debug queue after the first instruction.
  100.           */
  101.           _execDebug = 1;
  102.           return 0;
  103.     }
  104.         case PT_READ_I:    /* 1, read word from text segment */
  105.         case PT_READ_D:  { /* 2, read word from data segment */
  106.         status = Proc_Debug(pid,PROC_READ, sizeof(int),addr,
  107.                 &returnData);
  108.         errno = mapStatusToErrno(status);
  109.         return errno ? -1 : returnData; 
  110.         }
  111.         case PT_WRITE_I:    /* 4, write word into text segment */
  112.         case PT_WRITE_D: {  /* 5, write word into data segment */
  113.         status = Proc_Debug(pid,PROC_WRITE, sizeof(int),&data,addr);
  114.         if (status != 0) {
  115.         fprintf(stderr,
  116.             "Proc_Debug failed status = %x, pid = %x, addr = %x\n",
  117.             status, pid, addr);
  118.         }
  119.  
  120.         errno = mapStatusToErrno(status);
  121.         return errno ? -1 : data; 
  122.         }
  123.         case PT_CONTINUE: {       /* 7, continue process */
  124.         if (data != 0 && data != 1) {
  125.         if (kill(pid,data) != 0) {
  126.             perror("kill");
  127.             return -1;
  128.         }
  129.         }
  130.         status = Proc_Debug(pid,PROC_CONTINUE,0,0,0);
  131.         errno = mapStatusToErrno(status);
  132.         return errno ? -1 : 0; 
  133.         }
  134.         case PT_KILL: {      /* 8, terminate process */
  135.         if (kill(pid,SIGKILL) != 0) {
  136.         perror("kill");
  137.         return -1;
  138.         }
  139.         status= Proc_Debug(pid,PROC_DETACH_DEBUGGER,0,0,0);
  140.         (void) kill(pid,SIGKILL); /* Sometimes Sprite takes more than
  141.                        * one kill.
  142.                        */
  143.         (void) kill(pid,SIGCONT); 
  144.         status= Proc_Debug(pid,PROC_DETACH_DEBUGGER,0,0,0);
  145.         (void) kill(pid,SIGKILL); /* Sometimes Sprite takes more than
  146.                        * one kill.
  147.                        */
  148.         (void) kill(pid,SIGCONT); 
  149.         (void) kill(pid,SIGKILL); /* Sometimes Sprite takes more than
  150.                        * one kill.
  151.                        */
  152.         status= Proc_Debug(pid,PROC_DETACH_DEBUGGER,0,0,0);
  153.         if (status == PROC_INVALID_PID) {
  154.         status = SUCCESS;
  155.         }
  156.         errno = mapStatusToErrno(status);
  157.         return errno ? -1 : 0; 
  158.     }
  159.         case PT_STEP:{ /* 9, single step process */
  160.         status = Proc_Debug(pid,PROC_SINGLE_STEP,0,0,0);
  161.         errno = mapStatusToErrno(status);
  162.         return errno ? -1 : 0; 
  163.         }
  164.         case PT_ATTACH: {  /* 10, attach to an existing process */
  165.         status = Proc_Debug(pid,PROC_GET_THIS_DEBUG,0,0,0);
  166.         errno = mapStatusToErrno(status);
  167.         return errno ? -1 : 0; 
  168.     }
  169.         case PT_DETACH: {  /* 11, detach from a process */
  170.         if (data != 0 && data != 1) {
  171.         if (kill(pid,data) != 0) {
  172.             perror("kill");
  173.             return -1;
  174.         }
  175.         }
  176.         status = Proc_Debug(pid,PROC_DETACH_DEBUGGER,0,0,0);
  177.         errno = mapStatusToErrno(status);
  178.         return errno ? -1 : 0; 
  179.     }
  180.        case PT_READ_U: {   /* 3, read word from user struct */
  181.         Mach_RegState    *regPtr;
  182.         int            reg;
  183.         reg = (int) addr;
  184.         if ((reg >= 0) && (reg <  NPTRC_REGS)) {
  185.         status = Proc_Debug(pid,PROC_GET_DBG_STATE,0,0,&process_state);
  186.         errno = mapStatusToErrno(status);
  187.         if (errno) {
  188.             return -1;
  189.         }
  190.         regPtr = &process_state.regState;
  191.         if (reg < FPR_BASE) {
  192.             returnData = regPtr->regs[reg];
  193.         } else if (reg < FPR_BASE + NFP_REGS) {
  194.             returnData = regPtr->fpRegs[reg - FPR_BASE];
  195.         } else if (reg == PC) {
  196.             returnData = (int) regPtr->pc;
  197.         } else if (reg == MMHI) {
  198.             returnData = regPtr->mfhi;
  199.         } else if (reg == MMLO) {
  200.             returnData = regPtr->mflo;
  201.         } else if (reg == FPC_CSR) {
  202.             returnData = regPtr->fpStatusReg;
  203.         } else {
  204.             returnData = -1;
  205.         }
  206.         return returnData;
  207.         } else {
  208.         return -1;
  209.         }
  210.     }
  211.        case PT_WRITE_U: {   /* 6, write word into user struct */
  212.         Mach_RegState    *regPtr;
  213.         int            reg;
  214.         reg = (int) addr;
  215.         if ((reg >= 0) && (reg <  NPTRC_REGS)) {
  216.         status = Proc_Debug(pid,PROC_GET_DBG_STATE,0,0,&process_state);
  217.         errno = mapStatusToErrno(status);
  218.         if (errno) {
  219.             return -1;
  220.         }
  221.         regPtr = &process_state.regState;
  222.         if (reg < FPR_BASE) {
  223.             regPtr->regs[reg] = data;
  224.         } else if (reg < FPR_BASE + NFP_REGS) {
  225.             regPtr->fpRegs[reg - FPR_BASE] = data;
  226.         } else if (reg == PC) {
  227.             regPtr->pc = (Address) data;
  228.         } else if (reg == MMHI) {
  229.             regPtr->mfhi = data;
  230.         } else if (reg == MMLO) {
  231.             regPtr->mflo = data;
  232.         } else if (reg == FPC_CSR) {
  233.             regPtr->fpStatusReg = data;
  234.         } else {
  235.             return -1;
  236.         }
  237.         status = Proc_Debug(pid,PROC_SET_DBG_STATE,0,&process_state,0);
  238.         } else {
  239.         return -1;
  240.         }
  241.     }
  242.        default: {
  243.         return -1;
  244.     }
  245.     }
  246. }
  247.  
  248. /* 
  249.  *----------------------------------------------------------------------
  250.  *
  251.  * wait --
  252.  *
  253.  *    Emulate the Unix wait system call when used to wait for a 
  254.  *    process being ptraced.
  255.  *
  256.  * Results:
  257.  *    An integer.
  258.  *
  259.  * Side effects:
  260.  *
  261.  *----------------------------------------------------------------------
  262.  */
  263. int
  264. wait (statusPtr)
  265.     union wait *statusPtr;
  266. {
  267.     ReturnStatus    status;
  268.     Proc_DebugState process_state;
  269.     extern int inferior_pid;
  270.  
  271.     if (!inferior_pid) {
  272.     error("Trying to wait for nonexistant process");
  273.     }
  274.     /*
  275.      * Wait for this process to enter the debug list.
  276.      */
  277.     status = Proc_Debug(inferior_pid,PROC_GET_THIS_DEBUG,0,0,0);
  278.     if (status == SUCCESS) {
  279.     if (statusPtr == (union wait *) 0) {
  280.         goto reapChild;
  281.     }
  282.     status = Proc_Debug(inferior_pid,PROC_GET_DBG_STATE,0,0,&process_state);
  283.     if (status == SUCCESS) {
  284.         int unixSignal;
  285.             statusPtr->w_status = 0;
  286.             statusPtr->w_stopval = WSTOPPED;
  287.             if (process_state.termReason == PROC_TERM_SUSPENDED) {
  288.                 (void)Compat_SpriteSignalToUnix(process_state.termStatus,
  289.                            &unixSignal);
  290.                 statusPtr->w_stopsig = unixSignal;
  291.         if (process_state.termStatus == SIG_DEBUG ||
  292.             process_state.termStatus == SIG_TRACE_TRAP ||
  293.             process_state.termStatus == SIG_BREAKPOINT) {
  294.             statusPtr->w_stopsig = SIGTRAP;
  295.         }
  296.             } else if (process_state.termReason == PROC_TERM_SIGNALED ||
  297.                        process_state.termReason == PROC_TERM_RESUMED) {
  298.                 (void)Compat_SpriteSignalToUnix(process_state.termStatus, 
  299.                         &unixSignal);
  300.                 statusPtr->w_stopsig = unixSignal;
  301.         if (process_state.termStatus == SIG_DEBUG ||
  302.             process_state.termStatus == SIG_TRACE_TRAP ||
  303.             process_state.termStatus == SIG_BREAKPOINT) {
  304.             statusPtr->w_stopsig = SIGTRAP;
  305.         }
  306.             } else {
  307.         statusPtr->w_status = 0;
  308.                 statusPtr->w_retcode = process_state.termStatus;
  309.         (void) ptrace(PT_DETACH,inferior_pid,0,SIGKILL,0);
  310.             }
  311.         return inferior_pid;
  312.     }
  313.     }
  314. reapChild:
  315.     { 
  316.         Proc_PID    pid;
  317.     int        reason, childStatus, subStatus;
  318.     status = Proc_Wait(1, (int *) &inferior_pid, PROC_WAIT_BLOCK, 
  319.         &pid, &reason,  &childStatus, &subStatus, 
  320.         (Proc_ResUsage *) NULL);
  321.         if (statusPtr != NULL)  {
  322.         int        unixSignal;
  323.             statusPtr->w_status = 0;
  324.             if (reason == PROC_TERM_SUSPENDED) {
  325.                 (void)Compat_SpriteSignalToUnix(childStatus, &unixSignal);
  326.                 statusPtr->w_stopval = WSTOPPED;
  327.                 statusPtr->w_stopsig = unixSignal;
  328.             } else if (reason == PROC_TERM_SIGNALED ||
  329.                        reason == PROC_TERM_RESUMED) {
  330.                 (void)Compat_SpriteSignalToUnix(childStatus, &unixSignal);
  331.                 statusPtr->w_stopval = WSTOPPED;
  332.                 statusPtr->w_termsig = unixSignal;
  333.             } else {
  334.                 statusPtr->w_retcode = childStatus;
  335.         (void) ptrace(PT_DETACH,inferior_pid,0,SIGKILL,0);
  336.             }
  337.         }
  338.     }
  339.     return inferior_pid;
  340. }
  341.  
  342.  
  343.  
  344.  
  345. /* 
  346.  *----------------------------------------------------------------------
  347.  *
  348.  * mapStatusToErrno --
  349.  *
  350.  *    Map a Sprite status return code to a Unix errno. This is intended 
  351.  *    to work only on the status codes returns from Proc_Debug.
  352.  *
  353.  * Results:
  354.  *    An integer.
  355.  *
  356.  * Side effects:
  357.  *      None
  358.  *
  359.  *----------------------------------------------------------------------
  360.  */
  361.  
  362. static int
  363. mapStatusToErrno(status)
  364.     ReturnStatus    status;
  365. {
  366.     int    returnValue;
  367.  
  368.     if (status == SUCCESS) {
  369.     return 0;
  370.     }
  371.  
  372.     switch (status) {
  373.  
  374.     case PROC_INVALID_PID:
  375.     returnValue = ESRCH;
  376.     break;
  377.  
  378.     case SYS_INVALID_ARG:
  379.     returnValue = EINVAL;
  380.     break;
  381.  
  382.     case SYS_ARG_NOACCESS:
  383.     returnValue = EINVAL;
  384.     break;
  385.  
  386.     case GEN_ABORTED_BY_SIGNAL:
  387.     returnValue = EINTR;
  388.     break;
  389.  
  390.     default:
  391.     returnValue = EIO;
  392.     break;
  393.     }
  394.     return returnValue;
  395. }
  396.  
  397. @
  398.